package cn.lgwen.candy.runtime.core;

import cn.lgwen.candy.runtime.driver.ProcessorDriver;
import cn.lgwen.candy.runtime.driver.SinkDriver;
import cn.lgwen.candy.runtime.driver.SourceDriver;

import java.util.LinkedList;
import java.util.List;

/**
 * 2019/12/24
 * aven.wu
 * danxieai258@163.com
 */
public class Graph {

    private List<sourceDriverChain<?>> sourceChains;

    public void addSourceChains(sourceDriverChain<?> sourceDriverChain) {
        sourceChains.add(sourceDriverChain);
    }

    public List<sourceDriverChain<?>> getSourceChains() {
        return sourceChains;
    }


    public Graph() {
        sourceChains = new LinkedList<>();
    }

    public static class sourceDriverChain<O> {
        private SourceDriver<O> sourceDriver;

        private List<ProcessorDriversChain<O>> processorDriversChains;

        public void setSourceDriver(SourceDriver<O> sourceDriver) {
            this.sourceDriver = sourceDriver;
        }

        public sourceDriverChain(SourceDriver<O> sourceDriver
                                 ) {
            this.sourceDriver = sourceDriver;
            this.processorDriversChains = new LinkedList<>();
        }

        public void addProcessorDriver(ProcessorDriversChain<O> chain) {
            processorDriversChains.add(chain);
        }

        public SourceDriver<O> getSourceDriver() {
            return sourceDriver;
        }

        public List<ProcessorDriversChain<O>> getProcessorDriversChains() {
            return processorDriversChains;
        }
    }


    public static class ProcessorDriversChain<I> {
        private ProcessorDriver<I, ?> processorDriver;

        private List<ProcessorDriversChain<?>> processorDriversChains;

        private SinkDriver<I> sinkDriver;

        public ProcessorDriversChain() {
            this.processorDriversChains = new LinkedList<>();
        }

        public ProcessorDriversChain(SinkDriver<I> sinkDriver) {
            this.sinkDriver = sinkDriver;
            this.processorDriversChains = new LinkedList<>();
        }

        public void setSinkDriver(SinkDriver<I> sinkDriver) {
            this.sinkDriver = sinkDriver;
        }

        public void addProcessorDriverChain(ProcessorDriversChain<?> chain) {
            processorDriversChains.add(chain);
        }

        public void setProcessorDriver(ProcessorDriver<I, ?> processorDriver) {
            this.processorDriver = processorDriver;
        }

        public ProcessorDriver<I, ?> getProcessorDriver() {
            return processorDriver;
        }

        public List<ProcessorDriversChain<?>> getProcessorDriversChains() {
            return processorDriversChains;
        }

        public SinkDriver<I> getSinkDriver() {
            return sinkDriver;
        }
    }
}
